#include "game.h"
#include "graphics.h"
#include "input.h"
#include "level.h"
#include <SDL.h>
#include <algorithm>

namespace
{
	const int FPS = 60;
	const int MAX_FRAME_TIME = 6 * 1000 / FPS;
}

Game::Game()
{
	SDL_Init(SDL_INIT_EVERYTHING);
	this->Loop();
}

Game::~Game()
{

}

void Game::Loop()
{
	Graphics G;
	Input I;
	SDL_Event Event;

	CurrentLevel = 1;
	L = Level(G, CurrentLevel);
	P = Player(G);

	int LAST_UPDATE_TIME = SDL_GetTicks();
	while (true)
	{
		I.BeginFrame();
		if (SDL_PollEvent(&Event))
		{
			if (Event.type == SDL_KEYDOWN)
			{
				if (Event.key.repeat == 0)
				{
					I.KeyDownEvent(Event);
				}
			}
			else if(Event.type == SDL_KEYUP)
			{
				I.KeyUpEvent(Event);
			}
			else if(Event.type == SDL_QUIT)
			{
				return;
			}
		}
		if (I.WasKeyPressed(SDL_SCANCODE_ESCAPE) == true)
		{
			return;
		}
		if (I.WasKeyReleased(SDL_SCANCODE_D) == true || I.WasKeyReleased(SDL_SCANCODE_A) == true)
		{
			P.Still();
		}
		if (I.WasKeyPressed(SDL_SCANCODE_SPACE) == true)
		{
			P.Jump();
		}
		if (I.IsKeyHeld(SDL_SCANCODE_D) == true)
		{
			P.MoveRight();
		}
		if (I.IsKeyHeld(SDL_SCANCODE_A) == true)
		{
			P.MoveLeft();
		}
		if (P.X >= 1024)
		{
			CurrentLevel = CurrentLevel + 1;
			L = Level(G, CurrentLevel);
			P.X = 0;
		}
		const int CURRENT_TIME_MS = SDL_GetTicks();
		int ELAPSED_TIME_MS = CURRENT_TIME_MS - LAST_UPDATE_TIME;
		this->Update(std::min(ELAPSED_TIME_MS, MAX_FRAME_TIME), G);
		LAST_UPDATE_TIME = CURRENT_TIME_MS;
		this->Draw(G);
	}
}

void Game::Update(float ElapsedTime, Graphics &G)
{
	L.Update(ElapsedTime);
	P.Update(ElapsedTime, L);
}

void Game::Draw(Graphics &G)
{
	G.Clear();
	L.Draw(G);
	P.Draw(G);
	G.Flip();
}